/* -*- Mode: C -*- */
/******************************************************************************
*
*  Source File Name = tests2x.sqx
*
*  Component Name   = DB2 XML Extender
*
*  Descriptive Name = Test for mapping SQL to XML
*
*  Copyright = 5622-044 (c) Copyright IBM Corp 1987, 1997, 2001,2002
*              Licensed Materials - Program Property of IBM
*
*  Status = New code
*
*  Function = This client program tests the SQL-to-XML mapping stored
*             procedure of DB2 XML Extender.
*             It takes the arguments from the command line and calls the stored
*             procedure dxxGenXML.
*
*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlutil.h>
#include <sqlenv.h>
#include "sqlca.h"
#include "dxx.h"
#include "dxxrc.h"

/*******************************************************************
** main
*******************************************************************/
int main(int argc, char *argv[]) {
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
  char    dbname[18];
  char    result_tabname[160]; 
  char    result_colname[129];
  char    result_valname[129];
  sqlint32 overrideType = NO_OVERRIDE;
  struct override_t {
	char buf[32672];
  } *override;
  sqlint32 m;
  sqlint32 n;
  sqlint32 errCode;
  char    msgtext[2048];
  short   null_ind = -1;
  short   override_ind = -1;
  short   in_ind = 0;
  short   n_ind;
  short   errCode_ind;
  short   msgtext_ind;

  SQL TYPE is CLOB_FILE     dadfile;
  SQL TYPE is CLOB(100K)    *dadobj=NULL;

  struct {
    short len;
    char  data[1201];
  }  hvSQLStmt;
  char output[3000];
EXEC SQL END DECLARE SECTION;

 int     rc = 0, len, tmp_tbl_used=0;
 char    dadfilename[512];
  FILE   *testfile;
  int     ERROR_CASE = 0;
  char    errorMsg[1024] ;

  override=NULL;

  /* Process command-line arguments */

  if ((argc != 9) && (argc != 7) && (argc != 6)) {
    printf("Usage: %s dbname dadfilename result_tabname result_colname"
           " result_validcolname [max_ndocs|{-o overrideType override}]\n",
           argv[0]);
    return -1;
  }
  strcpy(dbname,         argv[1]);
  strcpy(dadfilename,    argv[2]);
  strcpy(result_tabname, argv[3]);
  strcpy(result_colname, argv[4]);
  strcpy(result_valname, argv[5]);
  m = (argc == 7)? atol(argv[6]): 0;
  override= (struct override_t *)calloc(1, sizeof(struct override_t));
  if (override == NULL) {
	printf("out of memory \n");
	goto exit;
  }
  dadobj = (struct dadobj_t *)calloc(1, sizeof(struct dadobj_t));
  if (dadobj==NULL) {
	printf("out of memory \n");
	goto exit;
  }
  if (argc > 6) {
    if (!strcmp(argv[6], "-o")) {
      /* Enable override. */
      overrideType =
        (!strcmp(argv[7],"SQL_OVERRIDE"))? SQL_OVERRIDE: XML_OVERRIDE;
      strcpy(override->buf, argv[8]);
      override_ind = 0;
    } else {
      override->buf[0]='\0';
      overrideType = NO_OVERRIDE;
    }
  }

  /* for error case */
  if (m == -1) ERROR_CASE = 1;

  /* Connect to database */
  fprintf(stdout, "Connecting to database %s\n", dbname);
  EXEC SQL CONNECT TO :dbname;

  if (!strncmp(result_tabname,"SESSION", 7)) {
	tmp_tbl_used=1;
    printf ("Creating global temporary table ...\n");
    if (strlen(result_valname) > 0) {
	  sprintf(hvSQLStmt.data,
	  "declare global temporary table result_tab(%s varchar(3000), %s integer) "
		   " not logged in mytsp", result_colname, result_valname);
	} else {
	  sprintf(hvSQLStmt.data,
	  "declare global temporary table result_tab(%s varchar(3000)) "
		   " not logged in mytsp", result_colname);
	}
    hvSQLStmt.len = strlen(hvSQLStmt.data);
    EXEC SQL EXECUTE IMMEDIATE :hvSQLStmt;
    printf ("Completion sqlcode = %d\n", SQLCODE);
  }


  /* Initialize the DAD CLOB object. */
  strcpy(dadfile.name, dadfilename);
  dadfile.name_length = strlen(dadfile.name);

  testfile = fopen( dadfile.name, "r" );
  if ( testfile != NULL ) {
	 fclose( testfile );
      }
  else {
        fprintf(stderr, "fopen() error.\n");
	fprintf(stderr, "Error accessing file: %s \n", dadfilename);
	rc = -1;
	goto exit;
        }

  dadfile.file_options = SQL_FILE_READ;
  /* DB2 would pass garbage if we directly fed
     xmlfile into our stored procedure. */
  EXEC SQL VALUES (:dadfile) INTO :*dadobj;


  /* Call the stored procedure. */
  if (ERROR_CASE)
    in_ind = -1;
  else
    in_ind = 0;

  printf ("Calling stored procedure db2xml!dxxGenXML ...\n");

  EXEC SQL CALL db2xml.dxxGenXML(:*dadobj:in_ind,
                                 :result_tabname:in_ind,
                                 :result_colname:in_ind,
                                 :result_valname:in_ind,
                                 :overrideType:in_ind,
                                 :*override:override_ind,
                                 :m:in_ind,
                                 :n:n_ind,
                                 :errCode:errCode_ind,
                                 :msgtext:msgtext_ind);

  /* Print the output parms. */
  printf("  n=%d:%d\n  errCode=%d:%d\n  msgtext'%s':%d\n",
         n, n_ind, errCode, errCode_ind, msgtext, msgtext_ind);
  if ( SQLCODE >= 0) { 
         if( SQLCODE > 0 ){
           sqlaintp( errorMsg , 1024 , 80 , &sqlca );
    	   printf("\n The warning message is \"%s\"  and it is being ignored.\n"
                , errorMsg );
		 }            


	if (!(errCode < DXX_ERRCODE_OK)) {

          if ( !tmp_tbl_used ) EXEC SQL COMMIT;

	  if (tmp_tbl_used) {
		sprintf(hvSQLStmt.data,
				"select %s from session.result_tab", result_colname);
		hvSQLStmt.len = strlen(hvSQLStmt.data);
		EXEC SQL PREPARE out_doc FROM :hvSQLStmt;
		EXEC SQL DECLARE c1 CURSOR FOR out_doc;
		EXEC SQL OPEN c1;
		
		printf ("\nResulting XML Document:\n");
		while (SQLCODE == 0) {
		  EXEC SQL FETCH c1 INTO :output;
		  if (SQLCODE ==0) 
		  printf ("%s\n\n", output);
		}
	  }
	} else {
	  EXEC SQL ROLLBACK;
	}
  }
  else	{
      sqlaintp( errorMsg , 1024 , 80 , &sqlca );
      printf("\n The error message is %s \n" , errorMsg );
      EXEC SQL ROLLBACK ;
   }
exit:
  if (override)
	free(override);
  if (dadobj)
	free(dadobj);
  return rc;
}
